home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / tests / fstrash / RCS / fstrash.c,v < prev    next >
Encoding:
Text File  |  1990-07-10  |  62.9 KB  |  2,281 lines

  1. head     1.4;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    jhh:1.4; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.4
  10. date     89.06.19.14.19.31;  author jhh;  state Exp;
  11. branches ;
  12. next     1.3;
  13.  
  14. 1.3
  15. date     89.01.06.08.16.54;  author brent;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     88.03.31.10.09.00;  author brent;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     87.10.20.11.01.23;  author brent;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @Make a filesystem on a disk
  32. @
  33.  
  34.  
  35. 1.4
  36. log
  37. @*** empty log message ***
  38. @
  39. text
  40. @/* 
  41.  * fstrash.c --
  42.  *
  43.  *    Format a domain to be a filesystem with lots of errors. This program 
  44.  *    is intended to be a test for fscheck. Refer to fstrash.man for details
  45.  *    on the filesystem created and the actions fscheck should take to 
  46.  *    correct it.
  47.  *    Warning - the trashed filesystem has been constructed by hand, and as
  48.  *    a result this code is very sensitive to changes. If you want to add a
  49.  *    new file you must do the following things:
  50.  *     - find an available file descriptor (see man page)
  51.  *     - find available data blocks (see man page)
  52.  *     - create a routine to fill in the descriptor (SetFooFD)
  53.  *     - add a call to this routine in WriteFileDesc
  54.  *     - mark the fd as in use in MakeFileDescBitmap
  55.  *     - mark the data blocks as in use in WriteBitmap
  56.  *     - add the file as an entry in a directory (WriteRootDirectory)
  57.  *     - if the new file is a directory create a new routine to fill in
  58.  *        the directory (WriteFoo) and add a call to this routine in
  59.  *        MakeFilesystem
  60.  *    Since you are creating a trashed file system you may want to skip some
  61.  *    of the above steps. Just make sure that you don't do something 
  62.  *    unexpected by using blocks that are already in use, forgetting to
  63.  *    add the file to a directory, etc. 
  64.  *
  65.  * Copyright 1989 Regents of the University of California
  66.  * Permission to use, copy, modify, and distribute this
  67.  * software and its documentation for any purpose and without
  68.  * fee is hereby granted, provided that the above copyright
  69.  * notice appear in all copies.  The University of California
  70.  * makes no representations about the suitability of this
  71.  * software for any purpose.  It is provided "as is" without
  72.  * express or implied warranty.
  73.  */
  74.  
  75. #ifndef lint
  76. static char rcsid[] = "$Header: /sprite/src/cmds.ancient/makeFilesystem/RCS/makeFilesystem.c,v 1.3 89/01/06 08:16:54 brent Exp $ SPRITE (Berkeley)";
  77. #endif not lint
  78.  
  79. #include "sprite.h"
  80. #include "option.h"
  81. #include "diskUtils.h"
  82. #include <stdio.h>
  83. #include <sys/file.h>
  84. #include <stdlib.h>
  85. #include <string.h>
  86.  
  87. /*
  88.  * Constants settable via the command line.
  89.  */
  90. int kbytesToFileDesc = 4;    /* The ratio of kbytes to
  91.                  * the number of file descriptors */
  92. Boolean printOnly = TRUE;    /* Stop after computing the domain header
  93.                  * and just print it out. No disk writes */
  94. Boolean copySuperBlock = FALSE;    /* Copy the super block from the first
  95.                  * disk partition to the one being formatted */
  96. Boolean makeFile = TRUE;    /* Make a file in the root directory,
  97.                  * this is used when testing the filesystem */
  98. Boolean overlapBlocks = FALSE;    /* Allow filesystem blocks to overlap track
  99.                  * boundaries.  Some disk systems can't deal. */
  100. Boolean rootFree = FALSE;    /* Mark the root as free */
  101. Boolean rootFile = FALSE;    /* Make the root a file */
  102. Boolean noRoot = FALSE;        /* Zero out the root fd and block 0 */
  103. /*
  104.  * The following are used to go from a command line like
  105.  * makeFilesystem -D rsd0 -P b
  106.  * to /dev/rsd0a     - for the partition that has the disk label
  107.  * and to /dev/rsd0b    - for the partition to format.
  108.  */
  109. char *deviceName;        /* Set to "rsd0" or "rxy1", etc. */
  110. char *partName;            /* Set to "a", "b", "c" ... "g" */
  111. char defaultFirstPartName[] = "a";
  112. char *firstPartName = defaultFirstPartName;
  113. char defaultDevDirectory[] = "/dev/";
  114. char *devDirectory = defaultDevDirectory;
  115.  
  116. Option optionArray[] = {
  117.     {OPT_STRING, "dev", (Address)&deviceName,
  118.     "Required: Name of device, eg \"rsd0\" or \"rxy1\""},
  119.     {OPT_STRING, "part", (Address)&partName,
  120.     "Required: Partition ID: (a, b, c, d, e, f, g)"},
  121.     {OPT_TRUE, "overlap", (Address)&overlapBlocks,
  122.     "Overlap filesystem blocks across track boundaries (FALSE)"},
  123.     {OPT_TRUE, "copySuper", (Address)©SuperBlock,
  124.     "Copy the super block to the partition (FALSE)"},
  125.     {OPT_INT, "ratio", (Address)&kbytesToFileDesc,
  126.     "Ratio of Kbytes to file descriptors (4)"},
  127.     {OPT_TRUE, "test", (Address)&printOnly,
  128.     "Print results, don't write disk (TRUE)"},
  129.     {OPT_FALSE, "write", (Address)&printOnly,
  130.     "Write the disk (FALSE)"},
  131.     {OPT_STRING, "dir", (Address)&devDirectory,
  132.     "Name of device directory (\"/dev/\")"},
  133.     {OPT_STRING, "initialPart", (Address)&firstPartName,
  134.     "Name of initial partition (\"a\")"},
  135.     {OPT_TRUE, "freeRoot", (Address)&rootFree,
  136.     "Mark root fd as being free. (FALSE)"},
  137.     {OPT_TRUE, "fileRoot", (Address)&rootFile,
  138.     "Mark root fd as being a file. (FALSE)"},
  139.     {OPT_TRUE, "noRoot", (Address)&noRoot,
  140.     "Zero out root fd and block 0 (FALSE)"},
  141.  
  142. };
  143. int numOptions = sizeof(optionArray) / sizeof(Option);
  144.  
  145. /*
  146.  * Forward Declarations.
  147.  */
  148. void SetSummaryInfo();
  149. void SetDomainHeader();
  150. void SetDiskGeometry();
  151. void SetDomainParts();
  152. void SetRootFileDescriptor();
  153. void SetBadBlockFileDescriptor();
  154. void SetLostFoundFileDescriptor();
  155. void SetEmptyFileDescriptor();
  156. void SetTooBigFD();
  157. void SetTooSmallFD();
  158. void SetHoleFileFD();
  159. void SetHoleDirFD();
  160. void SetBadEntryFileFD();
  161. void SetFragFileFD();
  162. void SetCopyFragFileFD();
  163. void SetCopyBlockFileFD();
  164. void SetCopyIndBlockFileFD();
  165. void SetCopyBogusIndBlockFileFD();
  166. void SetDirFD();
  167. ReturnStatus WriteFileDesc();
  168. ReturnStatus WriteFileDescBitmap();
  169. ReturnStatus WriteBitmap();
  170. char *MakeFileDescBitmap();
  171.  
  172.  
  173. /*
  174.  *----------------------------------------------------------------------
  175.  *
  176.  * main --
  177.  *
  178.  *    Create the required file names from the command line
  179.  *    arguments.  Then open the first partition on the disk
  180.  *    because it contains the disk label, and open the partition
  181.  *    that is to be formatted.
  182.  *
  183.  * Results:
  184.  *    None.
  185.  *
  186.  * Side effects:
  187.  *    Calls MakeFilesystem
  188.  *
  189.  *----------------------------------------------------------------------
  190.  */
  191. main(argc, argv)
  192.     int argc;
  193.     char *argv[];
  194. {
  195.     ReturnStatus status;    /* status of system calls */
  196.     int firstPartFID;        /* File ID for first parition on the disk */
  197.     int partFID;        /* File ID for partiton to format */
  198.     char firstPartitionName[64];
  199.     char partitionName[64];
  200.     int partition;        /* Index of partition derived from the
  201.                  * partition name */
  202.     int spriteID;        /* Host ID of the machine with the disks */
  203.     Fs_Attributes attrs;
  204.     char     answer[100];
  205.  
  206.     (void)Opt_Parse(argc, argv,optionArray, numOptions, 0);
  207.  
  208.     status = SUCCESS;
  209.     if (deviceName == (char *)0) {
  210.     fprintf(stderr,"Specify device name with -dev option\n");
  211.     status = FAILURE;
  212.     }
  213.     if (partName == (char *)0) {
  214.     fprintf(stderr,"Specify partition with -part option\n");
  215.     status = FAILURE;
  216.     }
  217.     if (status != SUCCESS) {
  218.     exit(status);
  219.     }
  220.     if (!printOnly) {
  221.     printf("The \"-write\" option will cause fstrash to overwrite the current filesystem.\nDo you really want to do this?[y/n] ");
  222.     if (scanf("%10s",answer) != 1) {
  223.         exit(SUCCESS);
  224.     }
  225.     if ((*answer != 'y') && (*answer != 'Y')) {
  226.         exit(SUCCESS);
  227.     }
  228.     }
  229.  
  230.  
  231.     /*
  232.      * Gen up the name of the first partition on the disk,
  233.      * and the name of the parition that needs to be formatted.
  234.      */
  235.     (void) strcpy(firstPartitionName, devDirectory);    /* eg. /dev/ */
  236.     (void) strcpy(partitionName, devDirectory);
  237.     (void) strcat(firstPartitionName, deviceName);    /* eg. /dev/rxy0 */
  238.     (void) strcat(partitionName, deviceName);
  239.     (void) strcat(firstPartitionName, firstPartName);    /* eg. /dev/rxy0a */
  240.     (void) strcat(partitionName, partName);        /* eg. /dev/rxy0b */
  241.  
  242.  
  243.     firstPartFID = open(firstPartitionName, O_RDONLY);
  244.     if (firstPartFID < 0 ) {
  245.     perror("Can't open first partition");
  246.     exit(FAILURE);
  247.     }
  248.     partFID = open(partitionName, O_RDWR);
  249.     if (partFID < 0) {
  250.     perror("Can't open partition to format");
  251.     exit(FAILURE);
  252.     }
  253.  
  254.     partition = partName[0] - 'a';
  255.     if (partition < 0 || partition > 7) {
  256.     fprintf(stderr,
  257.            "Can't determine partition index from the partition name\n");
  258.     exit(FAILURE);
  259.     }
  260.  
  261.     /*
  262.      * Determine where the disk is located so we can set the
  263.      * spriteID in the header correctly.
  264.      */
  265.     Fs_GetAttributesID(firstPartFID, &attrs);
  266.     if (attrs.devServerID == FS_LOCALHOST_ID) {
  267.     Sys_GetMachineInfo(NULL, NULL, &spriteID);
  268.     printf("Making filesystem for local host, ID = 0x%x\n", spriteID);
  269.     } else {
  270.     spriteID = attrs.devServerID;
  271.     printf("Making filesystem for remote host 0x%x\n", spriteID);
  272.     }
  273.     printf("MakeFilesystem based on 4K filesystem blocks\n");
  274.     status = MakeFilesystem(firstPartFID, partFID, partition, spriteID);
  275.  
  276.     fflush(stderr);
  277.     fflush(stdout);
  278.     (void)close(firstPartFID);
  279.     (void)close(partFID);
  280.     exit(status);
  281. }
  282.  
  283. /*
  284.  *----------------------------------------------------------------------
  285.  *
  286.  * MakeFilesystem --
  287.  *
  288.  *    Format a disk partition, or domain.
  289.  *
  290.  * Results:
  291.  *    An error code.
  292.  *
  293.  * Side effects:
  294.  *    Write all over the disk partition.
  295.  *
  296.  *----------------------------------------------------------------------
  297.  */
  298. ReturnStatus
  299. MakeFilesystem(firstPartFID, partFID, partition, spriteID)
  300.     int firstPartFID;    /* Handle on the first partition of the disk */
  301.     int partFID;    /* Handle on the partition of the disk to format */
  302.     int partition;    /* Index of parition that is to be formatted */
  303.     int spriteID;    /* Host ID of the machine with the disks, this
  304.              * gets written on the disk and used at boot time */
  305. {
  306.     ReturnStatus status;
  307.     Disk_Info *diskInfoPtr;
  308.     FsDomainHeader *headerPtr;
  309.     FsSummaryInfo *summaryPtr;
  310.  
  311.     /*
  312.      * Read the copy of the super block at the beginning of the partition
  313.      * to find out basic disk geometry and where to write the domain header.
  314.      */
  315.     diskInfoPtr = Disk_ReadDiskInfo(firstPartFID, partition);
  316.     if (diskInfoPtr == (Disk_Info *)0) {
  317.     fprintf(stderr,"MakeFilesystem: Unable to read super block.\n");
  318.     return(FAILURE);
  319.     }
  320.  
  321.     headerPtr = (FsDomainHeader *)
  322.     malloc((unsigned) diskInfoPtr->numDomainSectors * DEV_BYTES_PER_SECTOR);
  323.     SetDomainHeader(diskInfoPtr, headerPtr, spriteID, partition);
  324.     Disk_PrintDomainHeader(headerPtr);
  325.  
  326.     if (!printOnly) {
  327.     if (copySuperBlock && partition != 0) {
  328.         status = CopySuperBlock(firstPartFID, partFID);
  329.         if (status != SUCCESS) {
  330.         perror("CopySuperBlock failed"); 
  331.         return(status);
  332.         }
  333.     }
  334.     status = Disk_SectorWrite(partFID, diskInfoPtr->domainSector,
  335.                 diskInfoPtr->numDomainSectors, (Address)headerPtr);
  336.     if (status != SUCCESS) {
  337.         perror("DomainHeader write failed");
  338.         return(status);
  339.     }
  340.     }
  341.     summaryPtr = (FsSummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  342.     SetSummaryInfo(diskInfoPtr, headerPtr, summaryPtr);
  343.     Disk_PrintSummaryInfo(summaryPtr);
  344.     if (!printOnly) {
  345.     status = Disk_SectorWrite(partFID, diskInfoPtr->summarySector, 1,
  346.                 (Address)summaryPtr);
  347.     if (status != SUCCESS) {
  348.         perror("Summary sector  write failed");
  349.         return(status);
  350.     }
  351.     }
  352.  
  353.     status = WriteFileDesc(headerPtr, partFID);
  354.     if (status != SUCCESS) {
  355.     perror("WriteFileDesc failed");
  356.     return(status);
  357.     }
  358.     status = WriteBitmap(headerPtr, partFID);
  359.     if (status != SUCCESS) {
  360.     perror("WriteBitmap failed");
  361.     return(status);
  362.     }
  363.     status = WriteRootDirectory(headerPtr, partFID);
  364.     if (status != SUCCESS) {
  365.     perror("WriteRootDirectory failed");
  366.     return(status);
  367.     }
  368.     status = WriteLostFoundDirectory(headerPtr, partFID);
  369.     if (status != SUCCESS) {
  370.     perror("WriteLostFoundDirectory failed");
  371.     return(status);
  372.     }
  373.     status = WriteEmptyDirectory(headerPtr, partFID, 17, 16, 64);
  374.     if (status != SUCCESS) {
  375.     perror("WriteEmptyDirectory failed");
  376.     return(status);
  377.     }
  378.     status = WriteEmptyDirectory(headerPtr, partFID, 9, 2, 32);
  379.     if (status != SUCCESS) {
  380.     perror("WriteEmptyDirectory failed");
  381.     return(status);
  382.     }
  383.     return(SUCCESS);
  384. }
  385.  
  386. /*
  387.  *----------------------------------------------------------------------
  388.  *
  389.  * CopySuperBlock --
  390.  *
  391.  *    Copy the super block from the first sector of the disk to
  392.  *    the first sector of the partition being formatted.
  393.  *
  394.  * Results:
  395.  *    A return code from the I/O.
  396.  *
  397.  * Side effects:
  398.  *    Writes on the zero'th sector of the partition.
  399.  *
  400.  *----------------------------------------------------------------------
  401.  */
  402. ReturnStatus
  403. CopySuperBlock(firstPartFID, partFID)
  404.     int firstPartFID;
  405.     int partFID;
  406. {
  407.     ReturnStatus status;
  408.     char *block;
  409.  
  410.     block = (char *)malloc(DEV_BYTES_PER_SECTOR);
  411.  
  412.     status = Disk_SectorRead(firstPartFID, 0, 1, block);
  413.     if (status != SUCCESS) {
  414.     return(status);
  415.     }
  416.     status = Disk_SectorWrite(partFID, 0, 1, block);
  417.     return(status);
  418. }
  419.  
  420. /*
  421.  *----------------------------------------------------------------------
  422.  *
  423.  * SetDomainHeader --
  424.  *
  425.  *    Compute the domain header based on the partition size and
  426.  *    other basic disk parameters.
  427.  *
  428.  * Results:
  429.  *    A return code.
  430.  *
  431.  * Side effects:
  432.  *    Fill in the domain header.
  433.  *
  434.  *----------------------------------------------------------------------
  435.  */
  436. void
  437. SetDomainHeader(diskInfoPtr, headerPtr, spriteID, partition)
  438.     Disk_Info *diskInfoPtr;    /* Information from the super block */
  439.     FsDomainHeader *headerPtr;    /* Reference to domain header to fill in */
  440.     int spriteID;        /* Host ID of machine with the disks */
  441.     int partition;        /* Index of partition to format */
  442. {
  443.     register FsGeometry *geoPtr;/* The layout information for the disk */
  444.  
  445.     headerPtr->magic = FS_DOMAIN_MAGIC;
  446.     headerPtr->firstCylinder = diskInfoPtr->firstCylinder;
  447.     headerPtr->numCylinders = diskInfoPtr->numCylinders;
  448.     /*
  449.      * The device.serverID from the disk is used during boot to discover
  450.      * the host"s spriteID if reverse arp couldn't find a host ID.  The
  451.      * unit number of disk indicates what partition of the disk this
  452.      * domain header applies to.  For example, both the "a" and "c" partitions
  453.      * typically start at sector zero, but only one is valid.  During boot
  454.      * time the unit number is used to decide which partition should be
  455.      * attached.
  456.      */
  457.     headerPtr->device.serverID = spriteID;
  458.     headerPtr->device.type = -1;
  459.     headerPtr->device.unit = partition;
  460.     headerPtr->device.data = (ClientData)-1;
  461.  
  462.     geoPtr = &headerPtr->geometry;
  463.     SetDiskGeometry(diskInfoPtr, geoPtr);
  464.  
  465.     SetDomainParts(diskInfoPtr, headerPtr);
  466. }
  467.  
  468. /*
  469.  *----------------------------------------------------------------------
  470.  *
  471.  * SetDiskGeometry --
  472.  *
  473.  *    This computes the rotational set arrangment depending on the
  474.  *    disk geometry.  The basic rules for this are that filesystem blocks
  475.  *    are skewed on successive tracks, and that the skewing pattern
  476.  *    repeats in either 2 or 4 tracks.  This is specific to the fact that
  477.  *    filesystem blocks are 4Kbytes.  This means that one disk track
  478.  *    contains N/4 filesystem blocks and that one sector per track
  479.  *    is wasted if there are an odd number of sectors per track.
  480.  *
  481.  * Results:
  482.  *    None.
  483.  *
  484.  * Side effects:
  485.  *    Fill in the geometry struct.
  486.  *
  487.  *----------------------------------------------------------------------
  488.  */
  489. void
  490. SetDiskGeometry(diskInfoPtr, geoPtr)
  491.     register Disk_Info *diskInfoPtr;/* Basic geometry information */
  492.     register FsGeometry *geoPtr;    /* Fancy geometry information */
  493. {
  494.     register int index;        /* Array index */
  495.     int numBlocks;        /* The number of blocks in a rotational set */
  496.     int tracksPerSet;        /* Total number of tracks in a rotational set */
  497.     int numTracks;        /* The number of tracks in the set so far */
  498.     int extraSectors;        /* The number of leftover sectors in a track */
  499.     int offset;            /* The sector offset within a track */
  500.     int startingOffset;        /* The offset of the first block in a track */
  501.     int offsetIncrement;    /* The skew of the starting offset on each
  502.                  * successive track of the rotational set */
  503.     Boolean overlap;        /* TRUE if filesystem blocks overlap tracks */
  504.  
  505.     geoPtr->numHeads = diskInfoPtr->numHeads;
  506.     geoPtr->sectorsPerTrack = diskInfoPtr->numSectors;
  507.  
  508.     /*
  509.      * Figure out some basic parameters of the rotational set.  The number
  510.      * of tracks in the set is either 2 or 4.  If 2, then the blocks on
  511.      * successive tracks are skewed by 1/2 a filesystem block.  If 4,
  512.      * blocks are skewed by 1/4 block.  A 4 track rotational set is best
  513.      * becasue there are more rotational positions.  If, however, it
  514.      * causes 2 or 3 wasted tracks at the end, or if blocks naturally
  515.      * overlap by 1/2 block, then only 2 tracks per rotational set are
  516.      * used.
  517.      */
  518.     switch(geoPtr->numHeads % 4) {
  519.     case 0:
  520.     case 1: {
  521.         extraSectors = geoPtr->sectorsPerTrack % DISK_SECTORS_PER_BLOCK;
  522.         if (extraSectors < DISK_SECTORS_PER_BLOCK/4) {
  523.         /*
  524.          * Not enough extra sectors to overlap blocks onto the
  525.          * next track.  The blocks will fit evenly on a track,
  526.          * but the blocks on the following tracks will be skewed.
  527.          */
  528.         tracksPerSet = 4;
  529.         overlap = FALSE;
  530.         offsetIncrement = DISK_SECTORS_PER_BLOCK/4;
  531.         } else if (extraSectors < DISK_SECTORS_PER_BLOCK/2) {
  532.         /*
  533.          * Enough to overlap the first 1/4 block onto the next track.
  534.          */
  535.         tracksPerSet = 4;
  536.         overlap = TRUE;
  537.         offsetIncrement = DISK_SECTORS_PER_BLOCK * 3/4;
  538.         } else if (extraSectors < DISK_SECTORS_PER_BLOCK * 3/4) {
  539.         /*
  540.          * Enough to overlap 1/2 block.
  541.          */
  542.         tracksPerSet = 2;
  543.         overlap = TRUE;
  544.         offsetIncrement = DISK_SECTORS_PER_BLOCK/2;
  545.         } else {
  546.         /*
  547.          * Enough to overlap 3/4 block.
  548.          */
  549.         tracksPerSet = 4;
  550.         overlap = TRUE;
  551.         offsetIncrement = DISK_SECTORS_PER_BLOCK/4;
  552.         }
  553.         break;
  554.     }
  555.     case 2:
  556.     case 3: {
  557.         /*
  558.          * Instead of wasting 2 or 3 tracks to have a 4 track rotational
  559.          * set, the rotational set is only 2 tracks long.  Also see if
  560.          * the blocks naturally overlap by 1/2 block.
  561.          */
  562.         tracksPerSet = 2;
  563.         offsetIncrement = DISK_SECTORS_PER_BLOCK/2;
  564.         if ((geoPtr->sectorsPerTrack % DISK_SECTORS_PER_BLOCK) <
  565.               DISK_SECTORS_PER_BLOCK/2) {
  566.         overlap = FALSE;
  567.         } else {
  568.         overlap = TRUE;
  569.         }
  570.     }
  571.     }
  572.     if (!overlapBlocks) {
  573.     overlap = FALSE;
  574.     offsetIncrement = 0;
  575.     }
  576.     printf("overlap %s, offsetIncrement %d\n", (overlap ? "TRUE" : "FALSE"),
  577.               offsetIncrement);
  578.     /*
  579.      * Determine rotational position of the blocks in the rotational set.
  580.      */
  581.     extraSectors = geoPtr->sectorsPerTrack;
  582.     startingOffset = 0;
  583.     offset = startingOffset;
  584.     for (numBlocks = 0, numTracks = 0 ; ; ) {
  585.     if (extraSectors >= DISK_SECTORS_PER_BLOCK) {
  586.         /*
  587.          * Ok to fit in another filesystem block on this track.
  588.          */
  589.         geoPtr->blockOffset[numBlocks] = offset;
  590.         numBlocks++;    
  591.         offset += DISK_SECTORS_PER_BLOCK;
  592.         extraSectors -= DISK_SECTORS_PER_BLOCK;
  593.     } else {
  594.         /*
  595.          * The current block has to take up room on the next track.
  596.          */
  597.         numTracks++;
  598.         if (numTracks < tracksPerSet) {
  599.         /*
  600.          * Ok to go to the next track.
  601.          */
  602.         startingOffset += offsetIncrement;
  603.         if (overlap) {
  604.             /*
  605.              * If the current block can overlap to the next track,
  606.              * use the current offset.  Because of the overlap
  607.              * there are fewer sectors available for blocks on
  608.              * the next track.
  609.              */
  610.             geoPtr->blockOffset[numBlocks] = offset;
  611.             numBlocks++;
  612.             extraSectors = geoPtr->sectorsPerTrack - startingOffset;
  613.         }
  614.         offset = startingOffset + numTracks * geoPtr->sectorsPerTrack;
  615.         if (!overlap) {
  616.             /*
  617.              * If no overlap the whole next track is available.
  618.              */
  619.             extraSectors = geoPtr->sectorsPerTrack;
  620.         }
  621.         } else {
  622.         /*
  623.          * Done.
  624.          */
  625.         for (index = numBlocks; index < FS_MAX_ROT_POSITIONS; index++){
  626.             geoPtr->blockOffset[index] = -1;
  627.         }
  628.         break;
  629.         }
  630.     }
  631.     }
  632.     geoPtr->blocksPerRotSet = numBlocks;
  633.     geoPtr->tracksPerRotSet = tracksPerSet;
  634.     geoPtr->rotSetsPerCyl = geoPtr->numHeads / tracksPerSet;
  635.     geoPtr->blocksPerCylinder = numBlocks * geoPtr->rotSetsPerCyl;
  636.  
  637.     /*
  638.      * Now the rotational positions have to be sorted so that rotationally
  639.      * optimal blocks can be found.  The array sortedOffsets is set so
  640.      * that the I'th element has the index into blockOffset which contains
  641.      * the I'th rotational position, eg.
  642.      *    blockOffset    sortedOffsets
  643.      *        0 (+0)        0
  644.      *        8 (+0)        2
  645.      *        4 (+17)        1
  646.      *       12 (+17)        3
  647.      */
  648.  
  649.     offsetIncrement = DISK_SECTORS_PER_BLOCK / tracksPerSet;
  650.     for (index = 0 ; index < FS_MAX_ROT_POSITIONS ; index++) {
  651.     geoPtr->sortedOffsets[index] = -1;
  652.     }
  653.     for (index = 0 ; index < numBlocks ; index++) {
  654.     offset = geoPtr->blockOffset[index] % geoPtr->sectorsPerTrack;
  655.     geoPtr->sortedOffsets[offset/offsetIncrement] = index;
  656.     }
  657. }
  658.  
  659. /*
  660.  *----------------------------------------------------------------------
  661.  *
  662.  * SetDomainParts --
  663.  *
  664.  *    Set up the way the domain is divided into 4 areas:  the bitmap
  665.  *    for the file descriptors, the file descriptors, the bitmap for
  666.  *    the data blocks, and the data blocks.
  667.  *
  668.  * Results:
  669.  *    The geometry information is completed.
  670.  *
  671.  * Side effects:
  672.  *    None.
  673.  *
  674.  *----------------------------------------------------------------------
  675.  */
  676. void
  677. SetDomainParts(diskInfoPtr, headerPtr)
  678.     register Disk_Info *diskInfoPtr;
  679.     register FsDomainHeader *headerPtr;
  680. {
  681.     register FsGeometry *geoPtr;
  682.     int numFiles;        /* Number of files computed from the size */
  683.     int numBlocks;        /* Number of blocks in the partition.  This
  684.                  * is computed and then dolled out to the
  685.                  * different things stored in the partition */
  686.     int offset;            /* Block offset within partition */
  687.     int numSectors;        /* Sectors per rotational set */
  688.     int numSets;        /* Number of reserved rotational sets */
  689.     int bitmapBytes;        /* Number of bytes taken up by a bitmap */
  690.     /*
  691.      * Set aside a number of blocks at the begining of the partition for
  692.      * things like the super block, the boot program, and the domain header.
  693.      * It is easiest to do this by reserving one or more rotational sets.
  694.      */
  695.     geoPtr = &headerPtr->geometry;
  696.     numSectors = geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack;
  697.     for ( numSets = 1; ; numSets++ ) {
  698.     if (numSets * numSectors >
  699.         diskInfoPtr->domainSector + diskInfoPtr->numDomainSectors) {
  700.         break;
  701.     }
  702.     }
  703.     printf("Reserving %d blocks for domain header, etc.\n",
  704.             numSets*geoPtr->blocksPerRotSet);
  705.     /*
  706.      * Determine the number of filesystem blocks available and compute a
  707.      * first guess at the number of file descriptors.  If at the end of
  708.      * the computation things don't fit nicely, then the number of files
  709.      * is changed and the computation is repeated.
  710.      */
  711.     numFiles = 0;
  712.     do {
  713.     numBlocks = geoPtr->blocksPerCylinder * diskInfoPtr->numCylinders -
  714.             numSets * geoPtr->blocksPerRotSet;
  715.     if (numFiles == 0) {
  716.         numFiles = numBlocks * DISK_KBYTES_PER_BLOCK / kbytesToFileDesc;
  717.     }
  718.     numFiles          &= ~(FS_FILE_DESC_PER_BLOCK-1);
  719.     offset              = numSets * geoPtr->blocksPerRotSet;
  720.  
  721.     headerPtr->fdBitmapOffset = offset;
  722.     bitmapBytes          = (numFiles - 1) / BITS_PER_BYTE + 1;
  723.     headerPtr->fdBitmapBlocks = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  724.     numBlocks          -= headerPtr->fdBitmapBlocks;
  725.     offset              += headerPtr->fdBitmapBlocks;
  726.  
  727.     headerPtr->fileDescOffset = offset;
  728.     headerPtr->numFileDesc      = numFiles;
  729.     numBlocks          -= numFiles / FS_FILE_DESC_PER_BLOCK;
  730.     offset              += numFiles / FS_FILE_DESC_PER_BLOCK;
  731.     /*
  732.      * The data blocks will start on a cylinder.  Try the next
  733.      * cylinder boundary after the start of the bitmap.
  734.      */
  735.     headerPtr->bitmapOffset      = offset;
  736.     headerPtr->dataOffset      = ((offset-1) / geoPtr->blocksPerCylinder + 1)
  737.                      * geoPtr->blocksPerCylinder;
  738.     headerPtr->dataBlocks      = headerPtr->numCylinders *
  739.                       geoPtr->blocksPerCylinder -
  740.                       headerPtr->dataOffset;
  741.     bitmapBytes          = (headerPtr->dataBlocks * DISK_KBYTES_PER_BLOCK -
  742.                        1) / BITS_PER_BYTE + 1;
  743.     headerPtr->bitmapBlocks      = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  744.     /*
  745.      * Check the size of the bit map against space available for it
  746.      * between the end of the file descriptors and the start of the
  747.      * data blocks.
  748.      */
  749.     if (headerPtr->dataOffset - headerPtr->bitmapOffset <
  750.         headerPtr->bitmapBlocks) {
  751.         int numBlocksNeeded;
  752.         /*
  753.          * Need more blocks to hold the bitmap.  Reduce the number
  754.          * of file descriptors to get the blocks and re-iterate.
  755.          */
  756.         numBlocksNeeded = headerPtr->bitmapBlocks -
  757.         (headerPtr->dataOffset - headerPtr->bitmapOffset);
  758.         numFiles -= numBlocksNeeded * FS_FILE_DESC_PER_BLOCK;
  759.     } else if (headerPtr->dataOffset - headerPtr->bitmapOffset >
  760.             headerPtr->bitmapBlocks) {
  761.         int extraBlocks;
  762.         /*
  763.          * There are extra blocks between the end of the file descriptors
  764.          * and the start of the bitmap.  Increase the number of
  765.          * file descriptors and re-iterate.
  766.          */
  767.         extraBlocks = headerPtr->dataOffset - headerPtr->bitmapOffset -
  768.             headerPtr->bitmapBlocks;
  769.         numFiles += extraBlocks * FS_FILE_DESC_PER_BLOCK;
  770.     }
  771.     } while (headerPtr->dataOffset - headerPtr->bitmapOffset !=
  772.         headerPtr->bitmapBlocks);
  773.     headerPtr->dataCylinders    = headerPtr->dataBlocks /
  774.                   geoPtr->blocksPerCylinder ;
  775. }
  776.  
  777. /*
  778.  *----------------------------------------------------------------------
  779.  *
  780.  * SetSummaryInfo --
  781.  *
  782.  *    This routine is out of date and writes bogus info to the disk.
  783.  *    Fscheck should fix the data anyway.
  784.  *
  785.  * Results:
  786.  *    A return code.
  787.  *
  788.  * Side effects:
  789.  *    Fill in the summary info.
  790.  *
  791.  *----------------------------------------------------------------------
  792.  */
  793. void
  794. SetSummaryInfo(diskInfoPtr, headerPtr, summaryPtr)
  795.     Disk_Info *diskInfoPtr;    /* Information from the super block */
  796.     FsDomainHeader *headerPtr;    /* Domain header to summarize */
  797.     FsSummaryInfo *summaryPtr;    /* Reference to summary info to fill in */
  798. {
  799.  
  800.     bzero((Address)summaryPtr, DEV_BYTES_PER_SECTOR);
  801.  
  802.     strcpy(summaryPtr->domainPrefix, "(new domain)");
  803.     /*
  804.      * 9 blocks are already allocated, one for the root directory,
  805.      * and 8 more for lost+found.
  806.      */
  807.     summaryPtr->numFreeKbytes = headerPtr->dataBlocks * (FS_BLOCK_SIZE / 1024)
  808.                 - 9;
  809.     /*
  810.      * 4 file descriptors are already used, 0 and 1 are reserved,
  811.      * 2 is for the root, and 3 is for lost+found.
  812.      */
  813.     summaryPtr->numFreeFileDesc = headerPtr->numFileDesc - 5;
  814.     if (makeFile) {
  815.     summaryPtr->numFreeFileDesc--;
  816.     }
  817.     /*
  818.      * The summary state field is unused.
  819.      */
  820.     summaryPtr->state = 0;
  821.     /*
  822.      * The domain number under which this disk partition is mounted is
  823.      * recorded on disk so servers re-attach disks under the same "name".
  824.      * We set it to the special value so it gets a new number assigned
  825.      * when it is first attached.
  826.      */
  827.     summaryPtr->domainNumber = -1;
  828.     /*
  829.      * The flags field is used to record whether or not the disk has been
  830.      * safely "sync"ed to disk upon shutdown.
  831.      */
  832.     summaryPtr->flags = 0;
  833.     summaryPtr->fixCount = 0;
  834. }
  835.  
  836. /*
  837.  *----------------------------------------------------------------------
  838.  *
  839.  * WriteFileDesc --
  840.  *
  841.  *    Write out the file descriptor array to disk.
  842.  *
  843.  * Results:
  844.  *    None.
  845.  *
  846.  * Side effects:
  847.  *    None.
  848.  *
  849.  *----------------------------------------------------------------------
  850.  */
  851. ReturnStatus
  852. WriteFileDesc(headerPtr, partFID)
  853.     register FsDomainHeader *headerPtr;
  854.     int partFID;    /* File handle for partition to format */
  855. {
  856.     ReturnStatus status;
  857.     char *bitmap;
  858.     char *block;
  859.     register FsFileDescriptor *fileDescPtr;
  860.     register int index;
  861.  
  862.     bitmap = MakeFileDescBitmap(headerPtr);
  863.     if (!printOnly) {
  864.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->fdBitmapOffset,
  865.                 headerPtr->fdBitmapBlocks, (Address)bitmap);
  866.     if (status != SUCCESS) {
  867.         return(status);
  868.     }
  869.     }
  870.     /*
  871.      * Make the first block of file descriptors.  This contains some
  872.      * canned file descriptors for the root, bad block file, and the
  873.      * lost and found directory.  For (early system) testing an empty file
  874.      * can also be created.
  875.      */
  876.     block = (char *)malloc(FS_BLOCK_SIZE);
  877.     bzero(block, FS_BLOCK_SIZE);
  878.     for (index = 0;
  879.          index < FS_FILE_DESC_PER_BLOCK;
  880.      index++ ) {
  881.     fileDescPtr = (FsFileDescriptor *)((int)block +
  882.                        index * FS_MAX_FILE_DESC_SIZE);
  883.     fileDescPtr->magic = FS_FD_MAGIC;
  884.     if (index < FS_BAD_BLOCK_FILE_NUMBER) {
  885.         fileDescPtr->flags = FS_FD_RESERVED;
  886.     } else if (index == FS_BAD_BLOCK_FILE_NUMBER) {
  887.         SetBadBlockFileDescriptor(fileDescPtr);
  888.     } else if (index == FS_ROOT_FILE_NUMBER) {
  889.         SetRootFileDescriptor(fileDescPtr);
  890.     } else if (index == FS_LOST_FOUND_FILE_NUMBER) {
  891.         SetLostFoundFileDescriptor(fileDescPtr);
  892.     } else if ((index == 4) && makeFile) {
  893.         SetEmptyFileDescriptor(fileDescPtr);
  894.     } else if ((index == 5)) {
  895.         SetEmptyFileDescriptor(fileDescPtr);
  896.     } else if ((index == 6)) {
  897.         SetTooBigFD(fileDescPtr);
  898.     } else if ((index == 7)) {
  899.         SetTooSmallFD(fileDescPtr);
  900.     } else if ((index == 8)) {
  901.         SetHoleFileFD(headerPtr, partFID, fileDescPtr);
  902.     } else if ((index == 9)) {
  903.         SetHoleDirFD(headerPtr, partFID, fileDescPtr);
  904.     } else if ((index == 10)) {
  905.         SetBadEntryFileFD(headerPtr, partFID, fileDescPtr);
  906.     } else if ((index == 11)) {
  907.         SetFragFileFD(fileDescPtr);    
  908.     } else if ((index == 12)) {
  909.         SetCopyFragFileFD(fileDescPtr);    
  910.     } else if ((index == 13)) {
  911.         SetCopyBlockFileFD(fileDescPtr);    
  912.     } else if ((index == 14)) {
  913.         SetCopyIndBlockFileFD(headerPtr, partFID, fileDescPtr);    
  914.     } else if ((index == 15)) {
  915.         SetCopyBogusIndBlockFileFD(headerPtr, partFID, fileDescPtr);    
  916.     } else if ((index == 16)) {
  917.         fileDescPtr->magic = ~FS_FD_MAGIC;
  918.     } else if ((index == 17)) {
  919.         SetDirFD(fileDescPtr);
  920.     } else if ((index == 18)) {
  921.         SetOutputFD(fileDescPtr);
  922.     } else {
  923.         fileDescPtr->flags = FS_FD_FREE;
  924.     }
  925.     }
  926.     if (!printOnly) {
  927.     /*
  928.      * Write out the first, specially hand crafted, block of file
  929.      * descriptors.
  930.      */
  931.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->fileDescOffset,
  932.                     1, (Address)block);
  933.     if (status != SUCCESS) {
  934.         return(status);
  935.     }
  936.     /*
  937.      * Redo the block for the remaining file descriptors
  938.      */
  939.     bzero(block, FS_BLOCK_SIZE);
  940.     for (index = 0;
  941.          index < FS_FILE_DESC_PER_BLOCK;
  942.          index++ ) {
  943.         fileDescPtr = (FsFileDescriptor *)((int)block + index *
  944.                            FS_MAX_FILE_DESC_SIZE);
  945.         fileDescPtr->magic = FS_FD_MAGIC;
  946.         fileDescPtr->flags = FS_FD_FREE;
  947.     }
  948.     /*
  949.      * Write out the remaining file descriptors.
  950.      */
  951.     for (index = FS_FILE_DESC_PER_BLOCK;
  952.          index < headerPtr->numFileDesc;
  953.          index += FS_FILE_DESC_PER_BLOCK) {
  954.         status = Disk_BlockWrite(partFID, headerPtr,
  955.              headerPtr->fileDescOffset + (index/FS_FILE_DESC_PER_BLOCK),
  956.              1, (Address)block);
  957.         if (status != SUCCESS) {
  958.         return(status);
  959.         }
  960.     }
  961.     } else {
  962.     status = SUCCESS;
  963.     }
  964.     return(status);
  965. }
  966.  
  967. /*
  968.  * This macro makes setting bits in the fd and data block bitmap easier.
  969.  */
  970.  
  971. #define SET(num)  {   bitmap[(num) >> 3] |=(1 << (7 - ((num) & 0x7))); }
  972.  
  973.  
  974. /*
  975.  *----------------------------------------------------------------------
  976.  *
  977.  * 
  978.  * MakeFileDescBitmap --
  979.  *
  980.  *    Compute out the bitmap for file descriptor array to disk.
  981.  *
  982.  * Results:
  983.  *    None.
  984.  *
  985.  * Side effects:
  986.  *    None.
  987.  *
  988.  *----------------------------------------------------------------------
  989.  */
  990. char *
  991. MakeFileDescBitmap(headerPtr)
  992.     register FsDomainHeader *headerPtr;
  993. {
  994.     register char *bitmap;
  995.     register int index;
  996.  
  997.     /*
  998.      * Allocate and initialize the bitmap to all 0"s to mean all free.
  999.      */
  1000.     bitmap = (char *)malloc((unsigned) headerPtr->fdBitmapBlocks *
  1001.                  FS_BLOCK_SIZE);
  1002.     bzero((Address)bitmap, headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  1003.  
  1004.     SET(0);
  1005.     SET(1);
  1006.     if (!noRoot) {
  1007.     SET(2);
  1008.     }
  1009.     SET(3);
  1010.     SET(4);
  1011.     SET(6);
  1012.     SET(7);
  1013.     SET(8);
  1014.     SET(9);
  1015.     SET(10);
  1016.     SET(11);
  1017.     SET(12);
  1018.     SET(13);
  1019.     SET(14);
  1020.     SET(15);
  1021.     /*
  1022.      * 16 is allocated but not marked in the bitmap.
  1023.      */
  1024.     SET(17);
  1025.     SET(18);
  1026.     /*
  1027.      * 20 is marked in the bitmap but not used.
  1028.      */
  1029.     SET(20);
  1030.     /*
  1031.      * Set the bits in the map at the end that don't correspond to
  1032.      * any existing file descriptors.
  1033.      */
  1034.     index = headerPtr->numFileDesc / BITS_PER_BYTE;
  1035.     if (headerPtr->numFileDesc % BITS_PER_BYTE) {
  1036.     register int bitIndex;
  1037.     /*
  1038.      * Take care the last byte that only has part of its bits set.
  1039.      */
  1040.     for (bitIndex = headerPtr->numFileDesc % BITS_PER_BYTE;
  1041.          bitIndex < BITS_PER_BYTE;
  1042.          bitIndex++) {
  1043.         bitmap[index] |= 1 << ((BITS_PER_BYTE - 1) - bitIndex);
  1044.     }
  1045.     index++;
  1046.     }
  1047.     for ( ; index < headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE; index++) {
  1048.     bitmap[index] = 0xff;
  1049.     }
  1050.  
  1051.     if (printOnly) {
  1052.     Disk_PrintFileDescBitmap(headerPtr, bitmap);
  1053.     }
  1054.     return(bitmap);
  1055. }
  1056.  
  1057. /* 
  1058.  * This macro makes setting an entire block (4 fragments) easier. The block
  1059.  * to set must be on a block boundary.
  1060.  */
  1061.  
  1062. #define SET4K(num)  {   bitmap[(num) >> 3] |=(0xf << (4 - ((num) & 0x7))); }
  1063.  
  1064.  
  1065. /*
  1066.  *----------------------------------------------------------------------
  1067.  *
  1068.  * WriteBitmap --
  1069.  *
  1070.  *    Write out the bitmap for the data blocks.  This knows that the
  1071.  *    first 1K fragment is allocated to the root directory and 8K is
  1072.  *    allocated to lost and found, plus lots of other blocks are allocated
  1073.  *    to the rest of the files.
  1074.  *
  1075.  * Results:
  1076.  *    A return code from the writes.
  1077.  *
  1078.  * Side effects:
  1079.  *    Write the bitmap.
  1080.  *
  1081.  *----------------------------------------------------------------------
  1082.  */
  1083. ReturnStatus
  1084. WriteBitmap(headerPtr, partFID)
  1085.     register FsDomainHeader *headerPtr;
  1086.     int partFID;
  1087. {
  1088.     ReturnStatus status;
  1089.     char *bitmap;
  1090.     int kbytesPerCyl;
  1091.     int bitmapBytesPerCyl;
  1092.     int index;
  1093.  
  1094.     bitmap = (char *)malloc((unsigned) headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1095.     bzero(bitmap, headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1096.     /*
  1097.      * Set the bit corresponding to the kbyte used for the root directory
  1098.      * and the next 8K reserved for lost and found.
  1099.      *   ________
  1100.      *    |0______7|    Bits are numbered like this in a byte.
  1101.      *
  1102.      * See fstrash.man for info on how these blocks are used
  1103.      */
  1104.     if (!noRoot) {
  1105.     SET(0);
  1106.     }
  1107.     SET(1);
  1108.     SET4K(4);
  1109.     SET(8);
  1110.     SET(9);
  1111.  
  1112.     SET(11);
  1113.     SET4K(12);
  1114.     SET(16);
  1115.     SET(17);
  1116.  
  1117.     SET4K(32);
  1118.     SET4K(36);
  1119.  
  1120.     SET4K(44);
  1121.     SET4K(48);
  1122.     SET4K(52);
  1123.     SET4K(56);
  1124.  
  1125.     SET(61);
  1126.     SET(62);
  1127.  
  1128.     SET(64);
  1129.  
  1130.     SET4K(68);
  1131.     SET4K(72);
  1132.  
  1133.     /*
  1134.      * The bitmap is organized by cylinder.  There are whole number of
  1135.      * bytes in the bitmap for each cylinder.  Each bit in the bitmap
  1136.      * corresponds to 1 kbyte on the disk.
  1137.      */
  1138.     kbytesPerCyl = headerPtr->geometry.blocksPerCylinder * DISK_KBYTES_PER_BLOCK;
  1139.     bitmapBytesPerCyl = (kbytesPerCyl - 1) / BITS_PER_BYTE + 1;
  1140.     if ((kbytesPerCyl % BITS_PER_BYTE) != 0) {
  1141.     /*
  1142.      * There are bits in the last byte of the bitmap for each cylinder
  1143.      * that don't have kbytes behind them.  Set those bits here so
  1144.      * the blocks don't get allocated.
  1145.      */
  1146.     register int extraBits;
  1147.     register int mask;
  1148.  
  1149.     extraBits = kbytesPerCyl % BITS_PER_BYTE;
  1150.     /*
  1151.      * Set up a mask that has the right part filled with 1"s.
  1152.      */
  1153.     mask = 0x0;
  1154.     for ( ; extraBits < BITS_PER_BYTE ; extraBits++) {
  1155.         mask |= 1 << ((BITS_PER_BYTE - 1) - extraBits);
  1156.     }
  1157.     for (index = 0;
  1158.          index < headerPtr->dataBlocks * DISK_KBYTES_PER_BLOCK / BITS_PER_BYTE;
  1159.          index += bitmapBytesPerCyl) {
  1160.         bitmap[index + bitmapBytesPerCyl - 1] |= mask;
  1161.     }
  1162.     }
  1163.     /*
  1164.      * Set the bits in the bitmap that correspond to non-existent cylinders;
  1165.      * the bitmap is allocated a whole number of blocks on the disk
  1166.      * so there are bytes at its end that don't have blocks behind them.
  1167.      */
  1168.  
  1169.     for (index = headerPtr->dataCylinders * bitmapBytesPerCyl;
  1170.      index < headerPtr->bitmapBlocks * FS_BLOCK_SIZE;
  1171.      index++) {
  1172.     bitmap[index] = 0xff;
  1173.     }
  1174.     if (printOnly) {
  1175.     Disk_PrintDataBlockBitmap(headerPtr, bitmap);
  1176.     status = SUCCESS;
  1177.     } else {
  1178.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->bitmapOffset,
  1179.                 headerPtr->bitmapBlocks, (Address)bitmap);
  1180.     }
  1181.     return(status);
  1182. }
  1183.  
  1184. /*
  1185.  *----------------------------------------------------------------------
  1186.  *
  1187.  * WriteRootDirectory --
  1188.  *
  1189.  *    Write the data blocks of the root directory.
  1190.  *
  1191.  * Results:
  1192.  *    A return code from the writes.
  1193.  *
  1194.  * Side effects:
  1195.  *    Write the root directory"s data block.
  1196.  *
  1197.  *----------------------------------------------------------------------
  1198.  */
  1199. ReturnStatus
  1200. WriteRootDirectory(headerPtr, partFID)
  1201.     register FsDomainHeader *headerPtr;
  1202.     int partFID;
  1203. {
  1204.     ReturnStatus status;
  1205.     char block[FS_BLOCK_SIZE];
  1206.     FsDirEntry *dirEntryPtr;
  1207.     int offset;
  1208.     int i;
  1209.  
  1210.     bzero((Address) block, FS_BLOCK_SIZE);
  1211.  
  1212.     if (!noRoot) {
  1213.  
  1214.     dirEntryPtr = (FsDirEntry *)block;
  1215.     
  1216.     offset = FillDirEntry(dirEntryPtr,".",FS_ROOT_FILE_NUMBER);
  1217.  
  1218.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  1219.     offset += FillDirEntry(dirEntryPtr,"..",FS_ROOT_FILE_NUMBER);
  1220.     
  1221.     /*
  1222.      * Add lost and found.
  1223.      */
  1224.     
  1225.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1226.     offset += FillDirEntry(dirEntryPtr,"lost+found",
  1227.                    FS_LOST_FOUND_FILE_NUMBER);
  1228.     
  1229.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1230.     offset += FillDirEntry(dirEntryPtr,"testFile",4);
  1231.     
  1232.     /*
  1233.      * file 5 is an unreferenced file
  1234.      */
  1235.     
  1236.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1237.     offset += FillDirEntry(dirEntryPtr,"tooBig",6);
  1238.     
  1239.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1240.     offset += FillDirEntry(dirEntryPtr,"tooSmall",7);
  1241.     
  1242.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1243.     offset += FillDirEntry(dirEntryPtr,"holeFile",8);
  1244.     
  1245.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1246.     offset += FillDirEntry(dirEntryPtr,"holeDir",9);
  1247.     
  1248.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1249.     offset += FillDirEntry(dirEntryPtr,"badIndexFile",10);
  1250.     
  1251.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1252.     offset += FillDirEntry(dirEntryPtr,"illegalFrag",11);
  1253.     
  1254.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1255.     offset += FillDirEntry(dirEntryPtr,"copyBadFrag",12);
  1256.     
  1257.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1258.     offset += FillDirEntry(dirEntryPtr,"copyBlock",13);
  1259.     
  1260.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1261.     offset += FillDirEntry(dirEntryPtr,"copyIndBlock",14);
  1262.     
  1263.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1264.     offset += FillDirEntry(dirEntryPtr,"copyBogusInd",15);
  1265.     /*
  1266.      * 16 and 17 are unreferenced.
  1267.      */
  1268.     
  1269.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  1270.     offset += FillDirEntry(dirEntryPtr,"output",18);
  1271.  
  1272.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset +
  1273.                     dirEntryPtr->recordLength;
  1274.  
  1275.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  1276.      i < FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  1277.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  1278.      dirEntryPtr->fileNumber = 0;
  1279.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  1280.      dirEntryPtr->nameLength = 0;
  1281.     }
  1282.  
  1283.     }
  1284.     if (printOnly) {
  1285.     printf("Root Directory\n");
  1286.     offset = 0;
  1287.     dirEntryPtr = (FsDirEntry *)block;
  1288.     while (offset + dirEntryPtr->recordLength != FS_DIR_BLOCK_SIZE) {
  1289.         Disk_PrintDirEntry(dirEntryPtr);
  1290.         offset += dirEntryPtr->recordLength;
  1291.         dirEntryPtr = (FsDirEntry *)((int)block + offset);
  1292.     }
  1293.     status = SUCCESS;
  1294.     } else {
  1295.     /*
  1296.      * This write trounces the data beyond the stuff allocated to
  1297.      * the root directory.  Currently this is ok and is done because
  1298.      * BlockWrite writes whole numbers of filesystem blocks.
  1299.      */
  1300.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset, 1,
  1301.                        block);
  1302.     }
  1303.     return(status);
  1304. }
  1305.  
  1306. /*
  1307.  *----------------------------------------------------------------------
  1308.  *
  1309.  * WriteLostFoundDirectory --
  1310.  *
  1311.  *    Write the data blocks of the lost and found directory.
  1312.  *
  1313.  * Results:
  1314.  *    A return code from the writes.
  1315.  *
  1316.  * Side effects:
  1317.  *    Write the root directory"s data block.
  1318.  *
  1319.  *----------------------------------------------------------------------
  1320.  */
  1321. ReturnStatus
  1322. WriteLostFoundDirectory(headerPtr, partFID)
  1323.     register FsDomainHeader *headerPtr;
  1324.     int partFID;
  1325. {
  1326.     ReturnStatus status;
  1327.     char *block;
  1328.     FsDirEntry *dirEntryPtr;
  1329.     char *fileName;
  1330.     int length;
  1331.     int offset;
  1332.     int    i;
  1333.  
  1334.     block = (char *)malloc(FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE);
  1335.     dirEntryPtr = (FsDirEntry *)block;
  1336.  
  1337.     fileName = ".";
  1338.     length = strlen(fileName);
  1339.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER;
  1340.     dirEntryPtr->recordLength = FsDirRecLength(length);
  1341.     dirEntryPtr->nameLength = length;
  1342.     strcpy(dirEntryPtr->fileName, fileName);
  1343.     offset = dirEntryPtr->recordLength;
  1344.  
  1345.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  1346.     fileName = "..";
  1347.     length = strlen(fileName);
  1348.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  1349.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  1350.     dirEntryPtr->nameLength = length;
  1351.     strcpy(dirEntryPtr->fileName, fileName);
  1352.  
  1353.     /*
  1354.      * Fill out the rest of the directory with empty blocks.
  1355.      */
  1356.  
  1357.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  1358.      i < FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  1359.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  1360.      dirEntryPtr->fileNumber = 0;
  1361.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  1362.      dirEntryPtr->nameLength = 0;
  1363.     }
  1364.     if (printOnly) {
  1365.     printf("Lost+found Directory\n");
  1366.     offset = 0;
  1367.     dirEntryPtr = (FsDirEntry *)block;
  1368.     Disk_PrintDirEntry(dirEntryPtr);
  1369.     offset += dirEntryPtr->recordLength;
  1370.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  1371.     Disk_PrintDirEntry(dirEntryPtr);
  1372.     status = SUCCESS;
  1373.     } else {
  1374.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 1,
  1375.                 FS_NUM_LOST_FOUND_BLOCKS, block);
  1376.     }
  1377.     return(status);
  1378. }
  1379.  
  1380. /*
  1381.  *----------------------------------------------------------------------
  1382.  *
  1383.  * WriteEmptyDirectory --
  1384.  *
  1385.  *    Write the data blocks of the empty directory (file 17).
  1386.  *
  1387.  * Results:
  1388.  *    A return code from the writes.
  1389.  *
  1390.  * Side effects:
  1391.  *    None.
  1392.  *
  1393.  *----------------------------------------------------------------------
  1394.  */
  1395. ReturnStatus
  1396. WriteEmptyDirectory(headerPtr, partFID, selfFdNum, parentFdNum, blockNum)
  1397.     register FsDomainHeader *headerPtr;
  1398.     int partFID;
  1399.     int selfFdNum;
  1400.     int parentFdNum;
  1401.     int blockNum;
  1402. {
  1403.     ReturnStatus status;
  1404.     char *block;
  1405.     FsDirEntry *dirEntryPtr;
  1406.     char *fileName;
  1407.     int length;
  1408.     int offset;
  1409.     int    i;
  1410.  
  1411.     block = (char *)malloc(FS_BLOCK_SIZE);
  1412.     dirEntryPtr = (FsDirEntry *)block;
  1413.  
  1414.     fileName = ".";
  1415.     length = strlen(fileName);
  1416.     dirEntryPtr->fileNumber = selfFdNum;
  1417.     dirEntryPtr->recordLength = FsDirRecLength(length);
  1418.     dirEntryPtr->nameLength = length;
  1419.     strcpy(dirEntryPtr->fileName, fileName);
  1420.     offset = dirEntryPtr->recordLength;
  1421.  
  1422.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  1423.     fileName = "..";
  1424.     length = strlen(fileName);
  1425.     dirEntryPtr->fileNumber = parentFdNum;
  1426.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  1427.     dirEntryPtr->nameLength = length;
  1428.     strcpy(dirEntryPtr->fileName, fileName);
  1429.  
  1430.     /*
  1431.      * Fill out the rest of the directory with empty blocks.
  1432.      */
  1433.  
  1434.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  1435.      i < FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  1436.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  1437.      dirEntryPtr->fileNumber = 0;
  1438.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  1439.      dirEntryPtr->nameLength = 0;
  1440.     }
  1441.     if (printOnly) {
  1442.     printf("empty Directory\n");
  1443.     offset = 0;
  1444.     dirEntryPtr = (FsDirEntry *)block;
  1445.     Disk_PrintDirEntry(dirEntryPtr);
  1446.     offset += dirEntryPtr->recordLength;
  1447.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  1448.     Disk_PrintDirEntry(dirEntryPtr);
  1449.     status = SUCCESS;
  1450.     } else {
  1451.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 
  1452.                 (blockNum / FS_FRAGMENTS_PER_BLOCK),
  1453.                 1, block);
  1454.     }
  1455.     return(status);
  1456. }
  1457.  
  1458. /*
  1459.  *----------------------------------------------------------------------
  1460.  *
  1461.  *  FillDirEntry--
  1462.  *
  1463.  *    Fills in the directory entry.
  1464.  *
  1465.  * Results:
  1466.  *    None
  1467.  *
  1468.  * Side effects:
  1469.  *    None
  1470.  *
  1471.  *----------------------------------------------------------------------
  1472.  */
  1473. int
  1474. FillDirEntry(dirEntryPtr, fileName, fileNum)
  1475.     FsDirEntry *dirEntryPtr;
  1476.     char *fileName;
  1477.     int fileNum;
  1478. {
  1479.     int length;
  1480.  
  1481.     length = strlen(fileName);
  1482.     dirEntryPtr->fileNumber = fileNum;
  1483.     dirEntryPtr->recordLength = FsDirRecLength(length);
  1484.     dirEntryPtr->nameLength = length;
  1485.     strcpy(dirEntryPtr->fileName, fileName);
  1486.     return dirEntryPtr->recordLength;
  1487. }
  1488. @
  1489.  
  1490.  
  1491. 1.3
  1492. log
  1493. @Fixed include
  1494. @
  1495. text
  1496. @d2 1
  1497. a2 1
  1498.  * makeFilesystem.c --
  1499. d4 30
  1500. a33 4
  1501.  *    Format a domain to be an empty domain.
  1502.  *
  1503.  * Copyright (C) 1986 Regents of the University of California
  1504.  * All rights reserved.
  1505. d37 1
  1506. a37 1
  1507. static char rcsid[] = "$Header: makeFilesystem.c,v 1.2 88/03/31 10:09:00 brent Exp $ SPRITE (Berkeley)";
  1508. a41 1
  1509. #include "io.h"
  1510. d43 4
  1511. d57 1
  1512. a57 1
  1513. Boolean makeFile = FALSE;    /* Make a file in the root directory,
  1514. d61 3
  1515. d78 1
  1516. a78 1
  1517.     {OPT_STRING, 'D', (Address)&deviceName,
  1518. d80 1
  1519. a80 1
  1520.     {OPT_STRING, 'P', (Address)&partName,
  1521. d82 3
  1522. a84 5
  1523.     {OPT_TRUE, 'f', (Address)&makeFile,
  1524.     "Make a file in the root directory (FALSE)"},
  1525.     {OPT_TRUE, 'O', (Address)&overlapBlocks,
  1526.     "Overlap filesystem blocks accross track boundaries (FALSE)"},
  1527.     {OPT_TRUE, 'c', (Address)©SuperBlock,
  1528. d86 1
  1529. a86 1
  1530.     {OPT_INT, 'r', (Address)&kbytesToFileDesc,
  1531. d88 3
  1532. a90 3
  1533.     {OPT_TRUE, 't', (Address)&printOnly,
  1534.     "Test: print results, don't write disk (TRUE)"},
  1535.     {OPT_FALSE, 'W', (Address)&printOnly,
  1536. d92 1
  1537. a92 1
  1538.     {OPT_STRING, 'd', (Address)&devDirectory,
  1539. d94 1
  1540. a94 1
  1541.     {OPT_STRING, 'p', (Address)&firstPartName,
  1542. d96 7
  1543. d117 11
  1544. d165 1
  1545. d167 1
  1546. a167 1
  1547.     (void)Opt_Parse(&argc, argv, numOptions, optionArray);
  1548. d169 1
  1549. d171 1
  1550. a171 1
  1551.     Io_Print("Specify device name with -D option\n");
  1552. d175 1
  1553. a175 1
  1554.     Io_Print("Specify partition with -P option\n");
  1555. d179 10
  1556. a188 1
  1557.     Proc_Exit(status);
  1558. d191 1
  1559. d196 17
  1560. a212 18
  1561.     String_Copy(devDirectory, firstPartitionName);    /* eg. /dev/ */
  1562.     String_Copy(devDirectory, partitionName);
  1563.     String_Cat(deviceName, firstPartitionName);        /* eg. /dev/rxy0 */
  1564.     String_Cat(deviceName, partitionName);
  1565.     String_Cat(firstPartName, firstPartitionName);    /* eg. /dev/rxy0a */
  1566.     String_Cat(partName, partitionName);        /* eg. /dev/rxy0b */
  1567.  
  1568.     status = Fs_Open(firstPartitionName, FS_READ, 0, &firstPartFID);
  1569.     if (status != SUCCESS) {
  1570.     Io_PrintStream(io_StdErr, "Can't open first partition \"%s\" <%x>\n",
  1571.                   firstPartitionName, status);
  1572.     Proc_Exit(status);
  1573.     }
  1574.     status = Fs_Open(partitionName, FS_READ|FS_WRITE, 0, &partFID);
  1575.     if (status != SUCCESS) {
  1576.     Io_PrintStream(io_StdErr,"Can't open partition to format \"%s\" <%x>\n",
  1577.                   partitionName, status);
  1578.     Proc_Exit(status);
  1579. d217 1
  1580. a217 1
  1581.     Io_PrintStream(io_StdErr,
  1582. d219 1
  1583. a219 1
  1584.     Proc_Exit(FAILURE);
  1585. d229 1
  1586. a229 1
  1587.     Io_Print("Making filesystem for local host, ID = 0x%x\n", spriteID);
  1588. d232 1
  1589. a232 1
  1590.     Io_Print("Making filesystem for remote host 0x%x\n", spriteID);
  1591. d234 1
  1592. a234 1
  1593.     Io_Print("MakeFilesystem based on 4K filesystem blocks\n");
  1594. d237 5
  1595. a241 5
  1596.     Io_Flush(io_StdErr);
  1597.     Io_Flush(io_StdOut);
  1598.     (void)Fs_Close(firstPartFID);
  1599.     (void)Fs_Close(partFID);
  1600.     Proc_Exit(status);
  1601. d249 1
  1602. a249 1
  1603.  *    Format a disk partition, or domain, to be an empty filesystem.
  1604. d268 1
  1605. a268 2
  1606.     register int numBlocks;
  1607.     BasicDiskInfo *diskInfoPtr;
  1608. d276 3
  1609. a278 2
  1610.     diskInfoPtr = ReadBasicDiskInfo(firstPartFID, partition);
  1611.     if (diskInfoPtr == (BasicDiskInfo *)0) {
  1612. d282 2
  1613. a283 2
  1614.     headerPtr = (FsDomainHeader *) Mem_Alloc(diskInfoPtr->numDomainSectors *
  1615.                          DEV_BYTES_PER_SECTOR);
  1616. d285 1
  1617. a285 1
  1618.     PrintDomainHeader(headerPtr);
  1619. d291 1
  1620. a291 2
  1621.         Io_PrintStream(io_StdErr, "CopySuperBlock failed <%x>\n",
  1622.                       status);
  1623. d295 1
  1624. a295 1
  1625.     status = SectorWrite(partFID, diskInfoPtr->domainSector,
  1626. d298 1
  1627. a298 2
  1628.         Io_PrintStream(io_StdErr, "DomainHeader write failed <%x>\n",
  1629.                       status);
  1630. d302 1
  1631. a302 1
  1632.     summaryPtr = (FsSummaryInfo *) Mem_Alloc(DEV_BYTES_PER_SECTOR);
  1633. d304 1
  1634. a304 1
  1635.     PrintSummaryInfo(summaryPtr);
  1636. d306 1
  1637. a306 1
  1638.     status = SectorWrite(partFID, diskInfoPtr->summarySector, 1,
  1639. d309 1
  1640. a309 2
  1641.         Io_PrintStream(io_StdErr, "DomainHeader write failed <%x>\n",
  1642.                       status);
  1643. d316 1
  1644. a316 1
  1645.     Io_PrintStream(io_StdErr, "WriteFileDesc failed <%x>\n", status);
  1646. d321 1
  1647. a321 1
  1648.     Io_PrintStream(io_StdErr, "WriteBitmap failed <%x>\n", status);
  1649. d326 1
  1650. a326 1
  1651.     Io_PrintStream(io_StdErr, "WriteRootDirectory failed <%x>\n", status);
  1652. d331 11
  1653. a341 2
  1654.     Io_PrintStream(io_StdErr, "WriteLostFoundDirectory failed <%x>\n", 
  1655.             status);
  1656. d371 1
  1657. a371 1
  1658.     block = (char *)Mem_Alloc(DEV_BYTES_PER_SECTOR);
  1659. d373 1
  1660. a373 1
  1661.     status = SectorRead(firstPartFID, 0, 1, block);
  1662. d377 1
  1663. a377 1
  1664.     status = SectorWrite(partFID, 0, 1, block);
  1665. d399 1
  1666. a399 1
  1667.     BasicDiskInfo *diskInfoPtr;    /* Information from the super block */
  1668. a403 1
  1669.     ReturnStatus status;    /* General return code. */
  1670. d411 1
  1671. a411 1
  1672.      * the host's spriteID if reverse arp couldn't find a host ID.  The
  1673. d413 1
  1674. a413 1
  1675.      * domain header applies to.  For example, both the 'a' and 'c' partitions
  1676. d452 1
  1677. a452 1
  1678.     register BasicDiskInfo *diskInfoPtr;/* Basic geometry information */
  1679. d482 2
  1680. a483 2
  1681.         extraSectors = geoPtr->sectorsPerTrack % SECTORS_PER_BLOCK;
  1682.         if (extraSectors < SECTORS_PER_BLOCK/4) {
  1683. d491 2
  1684. a492 2
  1685.         offsetIncrement = SECTORS_PER_BLOCK/4;
  1686.         } else if (extraSectors < SECTORS_PER_BLOCK/2) {
  1687. d498 2
  1688. a499 2
  1689.         offsetIncrement = SECTORS_PER_BLOCK * 3/4;
  1690.         } else if (extraSectors < SECTORS_PER_BLOCK * 3/4) {
  1691. d505 1
  1692. a505 1
  1693.         offsetIncrement = SECTORS_PER_BLOCK/2;
  1694. d512 1
  1695. a512 1
  1696.         offsetIncrement = SECTORS_PER_BLOCK/4;
  1697. d524 3
  1698. a526 3
  1699.         offsetIncrement = SECTORS_PER_BLOCK/2;
  1700.         if ((geoPtr->sectorsPerTrack % SECTORS_PER_BLOCK) <
  1701.               SECTORS_PER_BLOCK/2) {
  1702. d537 1
  1703. a537 1
  1704.     Io_Print("overlap %s, offsetIncrement %d\n", (overlap ? "TRUE" : "FALSE"),
  1705. d546 1
  1706. a546 1
  1707.     if (extraSectors >= SECTORS_PER_BLOCK) {
  1708. d552 2
  1709. a553 2
  1710.         offset += SECTORS_PER_BLOCK;
  1711.         extraSectors -= SECTORS_PER_BLOCK;
  1712. d610 1
  1713. a610 1
  1714.     offsetIncrement = SECTORS_PER_BLOCK / tracksPerSet;
  1715. d639 1
  1716. a639 1
  1717.     register BasicDiskInfo *diskInfoPtr;
  1718. a650 1
  1719.     int index;            /* Array index */
  1720. d664 1
  1721. a664 1
  1722.     Io_Print("Reserving %d blocks for domain header, etc.\n",
  1723. d677 1
  1724. a677 1
  1725.         numFiles = numBlocks * KBYTES_PER_BLOCK / kbytesToFileDesc;
  1726. d679 1
  1727. a679 1
  1728.     numFiles          &= ~(FILE_DESC_PER_BLOCK-1);
  1729. d690 2
  1730. a691 2
  1731.     numBlocks          -= numFiles / FILE_DESC_PER_BLOCK;
  1732.     offset              += numFiles / FILE_DESC_PER_BLOCK;
  1733. d702 1
  1734. a702 1
  1735.     bitmapBytes          = (headerPtr->dataBlocks * KBYTES_PER_BLOCK -
  1736. d719 1
  1737. a719 1
  1738.         numFiles -= numBlocksNeeded * FILE_DESC_PER_BLOCK;
  1739. d730 1
  1740. a730 1
  1741.         numFiles += extraBlocks * FILE_DESC_PER_BLOCK;
  1742. d743 2
  1743. a744 2
  1744.  *    Initialize the summary information for the domain.  It is well
  1745.  *    known that this occupies one sector.
  1746. d756 1
  1747. a756 1
  1748.     BasicDiskInfo *diskInfoPtr;    /* Information from the super block */
  1749. a759 1
  1750.     ReturnStatus status;    /* General return code. */
  1751. d761 1
  1752. a761 1
  1753.     Byte_Zero(DEV_BYTES_PER_SECTOR, (Address)summaryPtr);
  1754. d763 1
  1755. a763 1
  1756.     String_Copy("(new domain)", summaryPtr->domainPrefix);
  1757. d774 1
  1758. a774 1
  1759.     summaryPtr->numFreeFileDesc = headerPtr->numFileDesc - 4;
  1760. d784 1
  1761. a784 1
  1762.      * recorded on disk so servers re-attach disks under the same 'name'.
  1763. d791 1
  1764. a791 1
  1765.      * safely 'sync'ed to disk upon shutdown.
  1766. d794 1
  1767. d825 1
  1768. a825 1
  1769.     status = BlockWrite(partFID, headerPtr, headerPtr->fdBitmapOffset,
  1770. d837 2
  1771. a838 2
  1772.     block = (char *)Mem_Alloc(FS_BLOCK_SIZE);
  1773.     Byte_Zero(FS_BLOCK_SIZE, block);
  1774. d840 1
  1775. a840 1
  1776.          index < FILE_DESC_PER_BLOCK;
  1777. d853 3
  1778. a855 1
  1779.     } else if ((index == FS_LOST_FOUND_FILE_NUMBER+1) && makeFile) {
  1780. d857 26
  1781. d892 1
  1782. a892 1
  1783.     status = BlockWrite(partFID, headerPtr, headerPtr->fileDescOffset,
  1784. d900 1
  1785. a900 1
  1786.     Byte_Zero(FS_BLOCK_SIZE, block);
  1787. d902 1
  1788. a902 1
  1789.          index < FILE_DESC_PER_BLOCK;
  1790. d912 1
  1791. a912 1
  1792.     for (index = FILE_DESC_PER_BLOCK;
  1793. d914 3
  1794. a916 3
  1795.          index += FILE_DESC_PER_BLOCK) {
  1796.         status = BlockWrite(partFID, headerPtr,
  1797.              headerPtr->fileDescOffset + (index/FILE_DESC_PER_BLOCK),
  1798. d927 1
  1799. a927 1
  1800.  
  1801. d929 1
  1802. a929 75
  1803.  *----------------------------------------------------------------------
  1804.  *
  1805.  * SetRootFileDescriptor --
  1806.  *
  1807.  *    Set up the file descriptor for the root directory.
  1808.  *
  1809.  * Results:
  1810.  *    Fill in the file descriptor.
  1811.  *
  1812.  * Side effects:
  1813.  *    None.
  1814.  *
  1815.  *----------------------------------------------------------------------
  1816.  */
  1817. void
  1818. SetRootFileDescriptor(fileDescPtr)
  1819.     register FsFileDescriptor *fileDescPtr;
  1820. {
  1821.     Time time;
  1822.     int index;
  1823.  
  1824.     fileDescPtr->flags = FS_FD_ALLOC;
  1825.     fileDescPtr->fileType = FS_DIRECTORY;
  1826.     fileDescPtr->permissions = 0755;
  1827.     fileDescPtr->uid = 0;
  1828.     fileDescPtr->gid = 0;
  1829.     fileDescPtr->lastByte = FS_DIR_BLOCK_SIZE-1;
  1830.     fileDescPtr->firstByte = -1;
  1831.     fileDescPtr->numLinks = 3;
  1832.     /*
  1833.      * Can't know device information because that depends on
  1834.      * the way the system is configured.
  1835.      */
  1836.     fileDescPtr->devServerID = -1;
  1837.     fileDescPtr->devType = -1;
  1838.     fileDescPtr->devUnit = -1;
  1839.  
  1840.     /*
  1841.      * Set the time stamps.  This assumes that universal time, not local
  1842.      * time, is used for time stamps.
  1843.      */
  1844.     Sys_GetTimeOfDay(&time, NULL, NULL);
  1845.     fileDescPtr->createTime = time.seconds;
  1846.     fileDescPtr->accessTime = 0;
  1847.     fileDescPtr->descModifyTime = time.seconds;
  1848.     fileDescPtr->dataModifyTime = time.seconds;
  1849.  
  1850.     /*
  1851.      * Place the data in the first filesystem block.
  1852.      */
  1853.     fileDescPtr->direct[0] = 0;
  1854.     for (index = 1; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  1855.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  1856.     }
  1857.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  1858.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  1859.     }
  1860.     fileDescPtr->numKbytes = 1;
  1861.     fileDescPtr->version = 1;
  1862. }
  1863.  
  1864. /*
  1865.  *----------------------------------------------------------------------
  1866.  *
  1867.  * SetBadBlockFileDescriptor --
  1868.  *
  1869.  *    Set up the file descriptor for the bad block file.
  1870.  *
  1871.  * Results:
  1872.  *    Fill in the file descriptor.
  1873.  *
  1874.  * Side effects:
  1875.  *    None.
  1876.  *
  1877.  *----------------------------------------------------------------------
  1878. a930 67
  1879. void
  1880. SetBadBlockFileDescriptor(fileDescPtr)
  1881.     register FsFileDescriptor *fileDescPtr;
  1882. {
  1883.     Time time;
  1884.     int index;
  1885.  
  1886.     fileDescPtr->flags = FS_FD_ALLOC;
  1887.     fileDescPtr->fileType = FS_FILE;
  1888.     fileDescPtr->permissions = 0000;
  1889.     fileDescPtr->uid = 0;
  1890.     fileDescPtr->gid = 0;
  1891.     fileDescPtr->lastByte = -1;
  1892.     fileDescPtr->firstByte = -1;
  1893.     fileDescPtr->numLinks = 0;        /* Intentionally unreferenced */
  1894.     /*
  1895.      * Can't know device information because that depends on
  1896.      * the way the system is configured.
  1897.      */
  1898.     fileDescPtr->devServerID = -1;
  1899.     fileDescPtr->devType = -1;
  1900.     fileDescPtr->devUnit = -1;
  1901.  
  1902.     /*
  1903.      * Set the time stamps.  This assumes that universal time, not local
  1904.      * time, is used for time stamps.
  1905.      */
  1906.     Sys_GetTimeOfDay(&time, NULL, NULL);
  1907.     fileDescPtr->createTime = time.seconds;
  1908.     fileDescPtr->accessTime = 0;
  1909.     fileDescPtr->descModifyTime = time.seconds;
  1910.     fileDescPtr->dataModifyTime = time.seconds;
  1911.  
  1912.     /*
  1913.      * Place the data in the first filesystem block.
  1914.      */
  1915.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  1916.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  1917.     }
  1918.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  1919.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  1920.     }
  1921.     fileDescPtr->numKbytes = 0;
  1922.     fileDescPtr->version = 1;
  1923. }
  1924.  
  1925. /*
  1926.  *----------------------------------------------------------------------
  1927.  *
  1928.  * SetLostFoundFileDescriptor --
  1929.  *
  1930.  *    Set up the file descriptor for the lost and found directory.
  1931.  *
  1932.  * Results:
  1933.  *    Fill in the file descriptor.
  1934.  *
  1935.  * Side effects:
  1936.  *    None.
  1937.  *
  1938.  *----------------------------------------------------------------------
  1939.  */
  1940. void
  1941. SetLostFoundFileDescriptor(fileDescPtr)
  1942.     register FsFileDescriptor *fileDescPtr;
  1943. {
  1944.     Time time;
  1945.     int index;
  1946. d932 1
  1947. a932 60
  1948.     fileDescPtr->flags = FS_FD_ALLOC;
  1949.     fileDescPtr->fileType = FS_DIRECTORY;
  1950.     fileDescPtr->permissions = 0755;
  1951.     fileDescPtr->uid = 0;
  1952.     fileDescPtr->gid = 0;
  1953.     fileDescPtr->lastByte = FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE - 1;
  1954.     fileDescPtr->firstByte = -1;
  1955.     fileDescPtr->numLinks = 2;
  1956.     /*
  1957.      * Can't know device information because that depends on
  1958.      * the way the system is configured.
  1959.      */
  1960.     fileDescPtr->devServerID = -1;
  1961.     fileDescPtr->devType = -1;
  1962.     fileDescPtr->devUnit = -1;
  1963.  
  1964.     /*
  1965.      * Set the time stamps.  This assumes that universal time, not local
  1966.      * time, is used for time stamps.
  1967.      */
  1968.     Sys_GetTimeOfDay(&time, NULL, NULL);
  1969.     fileDescPtr->createTime = time.seconds;
  1970.     fileDescPtr->accessTime = 0;
  1971.     fileDescPtr->descModifyTime = time.seconds;
  1972.     fileDescPtr->dataModifyTime = time.seconds;
  1973.  
  1974.     for (index = 0; index < FS_NUM_LOST_FOUND_BLOCKS ; index++) {
  1975.     fileDescPtr->direct[index] = FS_FRAGMENTS_PER_BLOCK * (index + 1);
  1976.     }
  1977.     for (; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  1978.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  1979.     }
  1980.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  1981.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  1982.     }
  1983.     fileDescPtr->numKbytes = 8;
  1984.     fileDescPtr->version = 1;
  1985. }
  1986.  
  1987. /*
  1988.  *----------------------------------------------------------------------
  1989.  *
  1990.  * SetEmptyFileDescriptor --
  1991.  *
  1992.  *    Set up a file descriptor for an empty file.
  1993.  *
  1994.  * Results:
  1995.  *    Fill in the file descriptor.
  1996.  *
  1997.  * Side effects:
  1998.  *    None.
  1999.  *
  2000.  *----------------------------------------------------------------------
  2001.  */
  2002. void
  2003. SetEmptyFileDescriptor(fileDescPtr)
  2004.     register FsFileDescriptor *fileDescPtr;
  2005. {
  2006.     Time time;
  2007.     int index;
  2008. a933 35
  2009.     fileDescPtr->flags = FS_FD_ALLOC;
  2010.     fileDescPtr->fileType = FS_FILE;
  2011.     fileDescPtr->permissions = 0666;
  2012.     fileDescPtr->uid = 0;
  2013.     fileDescPtr->gid = 0;
  2014.     fileDescPtr->lastByte = -1;
  2015.     fileDescPtr->firstByte = -1;
  2016.     fileDescPtr->numLinks = 1;
  2017.     /*
  2018.      * Can't know device information because that depends on
  2019.      * the way the system is configured.
  2020.      */
  2021.     fileDescPtr->devServerID = -1;
  2022.     fileDescPtr->devType = -1;
  2023.     fileDescPtr->devUnit = -1;
  2024.  
  2025.     /*
  2026.      * Set the time stamps.  This assumes that universal time, not local
  2027.      * time, is used for time stamps.
  2028.      */
  2029.     Sys_GetTimeOfDay(&time, NULL, NULL);
  2030.     fileDescPtr->createTime = time.seconds;
  2031.     fileDescPtr->accessTime = 0;
  2032.     fileDescPtr->descModifyTime = time.seconds;
  2033.     fileDescPtr->dataModifyTime = time.seconds;
  2034.  
  2035.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  2036.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  2037.     }
  2038.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  2039.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  2040.     }
  2041.     fileDescPtr->numKbytes = 0;
  2042.     fileDescPtr->version = 1;
  2043. }
  2044. d938 1
  2045. a954 1
  2046.     ReturnStatus status;
  2047. d959 1
  2048. a959 1
  2049.      * Allocate and initialize the bitmap to all 0's to mean all free.
  2050. d961 1
  2051. a961 1
  2052.     bitmap = (char *)Mem_Alloc(headerPtr->fdBitmapBlocks *
  2053. d963 1
  2054. a963 12
  2055.     Byte_Zero(headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE, (Address)bitmap);
  2056.  
  2057.     /*
  2058.      * Reserve file descriptors 0, 1, 2, and 3.  File number 0 is not used at 
  2059.      * all in the filesystem.  File number 1 is for the file with bad blocks.
  2060.      * File number 2 (FS_ROOT_FILE_NUMBER) is the root directory of the domain.
  2061.      * File number 3 (FS_LOST_FOUND_NUMBER) is the directory where lost
  2062.      * files are stored.
  2063.      *
  2064.      * IF THIS CHANGES remember to fix SetSummaryInfo
  2065.      */
  2066.     bitmap[0] |= 0xf0;
  2067. d965 22
  2068. d988 1
  2069. a988 1
  2070.      * Reserve file descriptor # 4 for an empty file.
  2071. d990 1
  2072. a990 3
  2073.     if (makeFile) {
  2074.     bitmap[0] |= 0x08;
  2075.     }
  2076. d1013 1
  2077. a1013 1
  2078.     PrintFileDescBitmap(headerPtr, bitmap);
  2079. d1017 8
  2080. d1033 2
  2081. a1034 1
  2082.  *    allocated to lost and found.
  2083. d1055 2
  2084. a1056 2
  2085.     bitmap = (char *)Mem_Alloc(headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  2086.     Byte_Zero(headerPtr->bitmapBlocks * FS_BLOCK_SIZE, bitmap);
  2087. d1063 1
  2088. a1063 1
  2089.      * IF THIS CHANGES remember to fix SetSummaryInfo()
  2090. d1065 29
  2091. a1093 2
  2092.     bitmap[0] |= 0x8f;
  2093.     bitmap[1] |= 0xf0;
  2094. d1099 1
  2095. a1099 1
  2096.     kbytesPerCyl = headerPtr->geometry.blocksPerCylinder * KBYTES_PER_BLOCK;
  2097. d1112 1
  2098. a1112 1
  2099.      * Set up a mask that has the right part filled with 1's.
  2100. d1119 1
  2101. a1119 1
  2102.          index < headerPtr->dataBlocks * KBYTES_PER_BLOCK / BITS_PER_BYTE;
  2103. d1136 1
  2104. a1136 1
  2105.     PrintDataBlockBitmap(headerPtr, bitmap);
  2106. d1139 1
  2107. a1139 1
  2108.     status = BlockWrite(partFID, headerPtr, headerPtr->bitmapOffset,
  2109. d1156 1
  2110. a1156 1
  2111.  *    Write the root directory's data block.
  2112. d1166 1
  2113. a1166 1
  2114.     char *block;
  2115. a1167 2
  2116.     char *fileName;
  2117.     int length;
  2118. d1169 1
  2119. d1171 1
  2120. a1171 2
  2121.     block = (char *)Mem_Alloc(FS_BLOCK_SIZE);
  2122.     dirEntryPtr = (FsDirEntry *)block;
  2123. d1173 1
  2124. a1173 7
  2125.     fileName = ".";
  2126.     length = String_Length(fileName);
  2127.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  2128.     dirEntryPtr->recordLength = FsDirRecLength(length);
  2129.     dirEntryPtr->nameLength = length;
  2130.     String_Copy(fileName, dirEntryPtr->fileName);
  2131.     offset = dirEntryPtr->recordLength;
  2132. d1175 3
  2133. a1177 8
  2134.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  2135.     fileName = "..";
  2136.     length = String_Length(fileName);
  2137.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  2138.     dirEntryPtr->recordLength = FsDirRecLength(length);
  2139.     dirEntryPtr->nameLength = length;
  2140.     String_Copy(fileName, dirEntryPtr->fileName);
  2141.     offset += dirEntryPtr->recordLength;
  2142. d1179 53
  2143. a1231 3
  2144.     /*
  2145.      * Add lost and found.
  2146.      */
  2147. d1233 2
  2148. a1234 6
  2149.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  2150.     fileName = "lost+found";
  2151.     length = String_Length(fileName);
  2152.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER;
  2153.     dirEntryPtr->nameLength = length;
  2154.     String_Copy(fileName, dirEntryPtr->fileName);
  2155. d1236 6
  2156. a1241 12
  2157.     if (!makeFile) {
  2158.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  2159.     } else {
  2160.     dirEntryPtr->recordLength = FsDirRecLength(length);
  2161.     offset += dirEntryPtr->recordLength;
  2162.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  2163.     fileName = "testFile";
  2164.     length = String_Length(fileName);
  2165.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER + 1;
  2166.     dirEntryPtr->nameLength = length;
  2167.     String_Copy(fileName, dirEntryPtr->fileName);
  2168.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  2169. d1244 1
  2170. d1246 1
  2171. a1246 1
  2172.     Io_Print("Root Directory\n");
  2173. d1249 2
  2174. a1250 5
  2175.     PrintDirEntry(dirEntryPtr);
  2176.     offset += dirEntryPtr->recordLength;
  2177.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  2178.     PrintDirEntry(dirEntryPtr);
  2179.     if (makeFile) {
  2180. a1252 1
  2181.         PrintDirEntry(dirEntryPtr);
  2182. d1261 1
  2183. a1261 1
  2184.     status = BlockWrite(partFID, headerPtr, headerPtr->dataOffset, 1,
  2185. d1278 1
  2186. a1278 1
  2187.  *    Write the root directory's data block.
  2188. d1295 1
  2189. a1295 1
  2190.     block = (char *)Mem_Alloc(FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE);
  2191. d1299 1
  2192. a1299 1
  2193.     length = String_Length(fileName);
  2194. d1303 1
  2195. a1303 1
  2196.     String_Copy(fileName, dirEntryPtr->fileName);
  2197. d1308 1
  2198. a1308 1
  2199.     length = String_Length(fileName);
  2200. d1312 1
  2201. a1312 1
  2202.     String_Copy(fileName, dirEntryPtr->fileName);
  2203. d1326 1
  2204. a1326 1
  2205.     Io_Print("Lost+found Directory\n");
  2206. d1329 1
  2207. a1329 1
  2208.     PrintDirEntry(dirEntryPtr);
  2209. d1332 1
  2210. a1332 1
  2211.     PrintDirEntry(dirEntryPtr);
  2212. d1335 1
  2213. a1335 1
  2214.     status = BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 1,
  2215. d1339 109
  2216. @
  2217.  
  2218.  
  2219. 1.2
  2220. log
  2221. @Added bad block file descriptor and summary sector
  2222. @
  2223. text
  2224. @d11 1
  2225. a11 1
  2226. static char rcsid[] = "$Header: makeFilesystem.c,v 1.1 87/10/20 11:01:23 brent Exp $ SPRITE (Berkeley)";
  2227. d17 1
  2228. a17 1
  2229. #include "fsDisk.h"
  2230. @
  2231.  
  2232.  
  2233. 1.1
  2234. log
  2235. @Initial revision
  2236. @
  2237. text
  2238. @d11 1
  2239. a11 1
  2240. static char rcsid[] = "$Header: makeFilesystem.c,v 1.7 87/07/14 11:43:34 brent Exp $ SPRITE (Berkeley)";
  2241. d77 1
  2242. d225 1
  2243. a225 1
  2244.     SetDomainHeader(diskInfoPtr, headerPtr, spriteID);
  2245. d333 1
  2246. a333 1
  2247. SetDomainHeader(diskInfoPtr, headerPtr, spriteID)
  2248. d337 1
  2249. d346 7
  2250. a352 3
  2251.      * Only the device.serverID from the disk is used.  It is examined
  2252.      * during boot to discover the host's spriteID if reverse arp
  2253.      * couldn't find a host ID.
  2254. d356 1
  2255. a356 1
  2256.     headerPtr->device.unit = -1;
  2257. d717 1
  2258. a717 1
  2259.      * The summary state is unused.
  2260. d720 12
  2261. d769 4
  2262. a772 1
  2263.      * Make the first block of file descriptors.
  2264. d782 1
  2265. a782 1
  2266.     if (index < ROOT_FILE_NUMBER) {
  2267. d784 3
  2268. a786 1
  2269.     } else if (index == ROOT_FILE_NUMBER) {
  2270. d902 61
  2271. d1112 1
  2272. a1112 1
  2273.      * File number 2 (ROOT_FILE_NUMBER) is the root directory of the domain.
  2274. d1276 1
  2275. a1276 1
  2276.     dirEntryPtr->fileNumber = ROOT_FILE_NUMBER;
  2277. d1285 1
  2278. a1285 1
  2279.     dirEntryPtr->fileNumber = ROOT_FILE_NUMBER;
  2280. @
  2281.